package cn.com.fattiger.framework.jcaptcha;

import java.awt.Color;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import com.octo.captcha.CaptchaException;
import com.octo.captcha.CaptchaFactory;
import com.octo.captcha.component.image.backgroundgenerator.UniColorBackgroundGenerator;
import com.octo.captcha.component.image.color.SingleColorGenerator;
import com.octo.captcha.component.image.fontgenerator.RandomFontGenerator;
import com.octo.captcha.component.image.textpaster.DecoratedRandomTextPaster;
import com.octo.captcha.component.image.textpaster.textdecorator.BaffleTextDecorator;
import com.octo.captcha.component.image.wordtoimage.ComposedWordToImage;
import com.octo.captcha.component.word.wordgenerator.RandomWordGenerator;
import com.octo.captcha.engine.GenericCaptchaEngine;
import com.octo.captcha.image.gimpy.GimpyFactory;
import com.octo.captcha.service.image.ImageCaptchaService;
import com.octo.captcha.service.multitype.GenericManageableCaptchaService;

/**
 * 图片验证码工厂
 * @author fattiger.xiaoyang
 * @date 2016/1/4
 * @qqGroup 48450434
 *
 */
public class JCaptcha {

	private GenericManageableCaptchaService genCaptchaService; //通用SPI
	private GenericCaptchaEngine captchaEngine; //认证码引擎
	private GimpyFactory factory;
	private RandomWordGenerator wordGenerator; //随机认证码生成器
	private ComposedWordToImage word2image;
	private RandomFontGenerator fontGenerator; //字体生成器
	private SingleColorGenerator backGroundColorGen;
	private UniColorBackgroundGenerator backgroundGenerator; //背景生成器
	private DecoratedRandomTextPaster decoratedPaster; //文本装饰器
	private BaffleTextDecorator baffleDecorator; //文本混淆 [未使用]
	private SingleColorGenerator fontColorGen; //字体颜色生成器
	//for genCaptchaService
	
	/***
	 * 垃圾收集器执行前 存储大小  default 256byte
	 */
	private int minCaptchaStoreSize = 256;  //垃圾收集器执行前 存储大小 captchaStoreLoadBeforeGarbageCollection
	/**
	 * 最大存储大小 default 512 byte
	 */
	private int maxCaptchaStoreSize = 512; //最大存储 , 不能小于前面那个参数
	/**
	 * 存储延迟 default 10秒
	 */
	private int minStorageDelayInSeconds = 10; //存储延迟数 单位秒 minGuarantedStorageDelayInSeconds
	///
	
	//for decoratedPaster
	/***
	 * 最大字符个数 10个
	 */
	private int maxWordLength = 4; //最大字符个数
	/***
	 * 最小字符个数 4个
	 */
	private int minWordLength = 4; //最小字符个数
	
	/**
	 * 图片高度 默认 40
	 */
	private int imageHeight = 40;
	/**
	 * 图片宽度 默认 100
	 */
	private int imageWidth = 100;
	/**
	 * 字体大小 20
	 */
	private int minFontSize = 30;
	/**
	 * 字体大小 26
	 */
	private int maxFontSize = 34;
	/**
	 * 随机字符
	 */
	private String acceptedChars="1234567890abcdefghigklmnopqrstuvwxyz";
	/***
	 * 干扰线 [无用]
	 */
	private int numberOfHolesPerGlyph=1;
	
	/**
	 * 字体颜色 rgb
	 */
	private int fontColor = Color.BLACK.getRGB();
	
	private int backGroundColor=Color.WHITE.getRGB();

	public int getMinCaptchaStoreSize() {
		return minCaptchaStoreSize;
	}

	public void setMinCaptchaStoreSize(int minCaptchaStoreSize) {
		this.minCaptchaStoreSize = minCaptchaStoreSize;
	}

	public int getMaxCaptchaStoreSize() {
		return maxCaptchaStoreSize;
	}

	public void setMaxCaptchaStoreSize(int maxCaptchaStoreSize) {
		this.maxCaptchaStoreSize = maxCaptchaStoreSize;
	}

	public int getMinGuarantedStorageDelayInSeconds() {
		return minStorageDelayInSeconds;
	}

	public void setMinGuarantedStorageDelayInSeconds(
			int minGuarantedStorageDelayInSeconds) {
		this.minStorageDelayInSeconds = minGuarantedStorageDelayInSeconds;
	}

	public int getMaxAcceptedWordLength() {
		return maxWordLength;
	}

	public void setMaxAcceptedWordLength(int maxAcceptedWordLength) {
		this.maxWordLength = maxAcceptedWordLength;
	}

	public int getMinAcceptedWordLength() {
		return minWordLength;
	}

	public void setMinAcceptedWordLength(int minAcceptedWordLength) {
		this.minWordLength = minAcceptedWordLength;
	}

	public int getImageHeight() {
		return imageHeight;
	}

	public void setImageHeight(int imageHeight) {
		this.imageHeight = imageHeight;
	}

	public int getImageWidth() {
		return imageWidth;
	}

	public void setImageWidth(int imageWidth) {
		this.imageWidth = imageWidth;
	}

	public int getMinFontSize() {
		return minFontSize;
	}

	public void setMinFontSize(int minFontSize) {
		this.minFontSize = minFontSize;
	}

	public int getMaxFontSize() {
		return maxFontSize;
	}

	public void setMaxFontSize(int maxFontSize) {
		this.maxFontSize = maxFontSize;
	}

	public String getAcceptedChars() {
		return acceptedChars;
	}

	public void setAcceptedChars(String acceptedChars) {
		this.acceptedChars = acceptedChars;
	}

	public int getNumberOfHolesPerGlyph() {
		return numberOfHolesPerGlyph;
	}

	public void setNumberOfHolesPerGlyph(int numberOfHolesPerGlyph) {
		this.numberOfHolesPerGlyph = numberOfHolesPerGlyph;
	}

	public int getFontColor() {
		return fontColor;
	}

	public void setFontColor(int fontColor) {
		this.fontColor = fontColor;
	}

	public int getBackGroundColor() {
		return backGroundColor;
	}

	public void setBackGroundColor(int backGroundColor) {
		this.backGroundColor = backGroundColor;
	}

	public ImageCaptchaService buildService() {
		fontColorGen=new SingleColorGenerator(new Color(fontColor));
		baffleDecorator = new BaffleTextDecorator(numberOfHolesPerGlyph, new Color(fontColor).brighter());
		decoratedPaster = new DecoratedRandomTextPaster(minWordLength, maxWordLength, fontColorGen, null);//new TextDecorator[]{baffleDecorator});
		Font[] fnt=new Font[]{new Font("Arial",Font.PLAIN,minFontSize),new Font("Arial",Font.PLAIN,maxFontSize)};
		fontGenerator = new RandomFontGenerator(minFontSize, maxFontSize,fnt);
		backGroundColorGen=new SingleColorGenerator(new Color(backGroundColor));
		backgroundGenerator=new UniColorBackgroundGenerator(imageWidth, imageHeight, backGroundColorGen);
		word2image = new ComposedWordToImage(fontGenerator, backgroundGenerator, decoratedPaster);
		wordGenerator = new RandomWordGenerator(acceptedChars);
		factory = new GimpyFactory(wordGenerator, word2image);

		captchaEngine = new GenericCaptchaEngine(new CaptchaFactory[] { factory });

		genCaptchaService = new GenericManageableCaptchaService(captchaEngine, minStorageDelayInSeconds, maxCaptchaStoreSize, minCaptchaStoreSize);

		return genCaptchaService;
	}
	
	private ImageCaptchaService getCaptchaService() {
		synchronized (genCaptchaService) {
			if(genCaptchaService==null){
				return buildService();
			}else{
				return genCaptchaService;
			}
		}
	}
	
	/***
	 * 得到图片
	 * @param id 标识符
	 * @return
	 */
	public BufferedImage getImageChallengeForID(String id){
		return getCaptchaService().getImageChallengeForID(id);
	}
	/***
	 * 验证 通过 {@link #getImageChallengeForID(String)} 得到的图片验证码
	 * @param id
	 * @param validCode
	 * @return
	 */
	public boolean validImageChallengeByID(String id,Object validCode){
		return getCaptchaService().validateResponseForID(id, validCode);
	}
	
	/***
	 * 最终得到图片
	 * @param id
	 * @return map {imge:bufferedImge:图片缓存, word:string:生成的随机数字}
	 */
	public Map<String,Object> getImage(){
		Map<String,Object> map=new HashMap<String, Object>(2);
		String word=wordGenerator.getWord(minWordLength);
		BufferedImage bi=null;
		while(bi==null){
			try {
				bi = word2image.getImage(word);
			} catch (CaptchaException e) {}
		}
		
		map.put("image", bi);
		map.put("word", word);
		
		return Collections.unmodifiableMap(map);
	}
	
	public static void main(String[] args) {
	}
	
}

